package com.hycc.cas;

import lombok.SneakyThrows;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicStampedReference;

/*
* 彻底解决CAS中的ABA问题
* */
public class CASDemo {

    @SneakyThrows
    public static void main(String[] args) {
        /*
        * AtomicStampedReference 比较Integer底层使用的是==
        * Integer对象超过-128~127后，就会自动产生新对象
        * 解决，使用小的数，或者将对象在外部创建 先new出来。
        * */
        Integer org = new Integer(2000);
        Integer mod = new Integer(2006);
        AtomicStampedReference<Integer> num = new AtomicStampedReference<>(org,1);

        new Thread(()->{
            int stamp = num.getStamp();
            System.out.println("a1=>"+stamp);
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println(num.compareAndSet(org, mod,stamp, stamp + 1));
            System.out.println("a2=>"+num.getStamp());

            System.out.println(num.compareAndSet(mod, org, stamp+1, stamp + 2));
            System.out.println("a3=>"+num.getStamp());

        },"a").start();

        new Thread(()->{
            int stamp = num.getStamp();
            System.out.println("b1=>"+stamp);

            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println(num.compareAndSet(org, 666, stamp, stamp + 1));
            System.out.println("b2=>"+num.getStamp());
        },"b").start();
    }
}
